package com.tuanzi.loan.business.repository.system.impl;

import static com.tuanzi.loan.generated.jooq.loan.tables.LoanDataPermissionRelation.LOAN_DATA_PERMISSION_RELATION;
import static com.tuanzi.loan.generated.jooq.loan.tables.LoanFunctionalPermissionRelation.LOAN_FUNCTIONAL_PERMISSION_RELATION;
import static com.tuanzi.loan.generated.jooq.loan.tables.LoanPartner.LOAN_PARTNER;
import static com.tuanzi.loan.generated.jooq.loan.tables.LoanRole.LOAN_ROLE;
import static com.tuanzi.loan.generated.jooq.loan.tables.LoanSystemUser.LOAN_SYSTEM_USER;
import static com.tuanzi.loan.generated.jooq.loan.tables.LoanUserRole.LOAN_USER_ROLE;

import java.sql.Timestamp;
import java.util.List;

import org.jooq.Record;
import org.jooq.RecordMapper;
import org.jooq.impl.TableImpl;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Repository;

import com.tuanzi.loan.business.entity.system.SystemUser;
import com.tuanzi.loan.business.repository.system.custom.SystemUserRepositoryCustom;
import com.tuanzi.loan.core.repository.JOOQBaseRepository;
import com.tuanzi.loan.vo.request.system.SystemUserSearchRequest;
import com.tuanzi.loan.vo.response.system.SystemUserSearchResponse;

/**
 * @author Ray 2017/09/21
 */
@Repository
@SuppressWarnings({ "rawtypes" })
public class SystemUserRepositoryImpl extends JOOQBaseRepository implements SystemUserRepositoryCustom {

	@Override
	protected TableImpl getTable() {
		return LOAN_SYSTEM_USER;
	}

	@Override
	public Page<SystemUserSearchResponse> list(SystemUserSearchRequest searchRequest, Pageable pageable) {
		fields(LOAN_SYSTEM_USER.ID, LOAN_SYSTEM_USER.NAME, LOAN_SYSTEM_USER.ACCOUNT, LOAN_SYSTEM_USER.ENABLE, LOAN_SYSTEM_USER.LOCKED, LOAN_SYSTEM_USER.EMAIL,
				LOAN_SYSTEM_USER.PHONE, LOAN_SYSTEM_USER.LAST_LOGIN_TIME, LOAN_PARTNER.NAME, LOAN_FUNCTIONAL_PERMISSION_RELATION.ID, LOAN_DATA_PERMISSION_RELATION.ID,
				LOAN_USER_ROLE.ID);

		leftJoin(LOAN_FUNCTIONAL_PERMISSION_RELATION, LOAN_SYSTEM_USER.ID.eq(LOAN_FUNCTIONAL_PERMISSION_RELATION.RELATION_ID)
				.and(LOAN_FUNCTIONAL_PERMISSION_RELATION.PERMISSION_ID.eq(searchRequest.getFunctionalPermissionId())));

		leftJoin(LOAN_DATA_PERMISSION_RELATION,
				LOAN_SYSTEM_USER.ID.eq(LOAN_DATA_PERMISSION_RELATION.RELATION_ID).and(LOAN_DATA_PERMISSION_RELATION.PERMISSION_ID.eq(searchRequest.getDataPermissionId())));

		leftJoin(LOAN_USER_ROLE, LOAN_SYSTEM_USER.ID.eq(LOAN_USER_ROLE.USER_ID).and(LOAN_USER_ROLE.ROLE_ID.eq(searchRequest.getRoleId())));

		leftJoin(LOAN_PARTNER, LOAN_PARTNER.ID.eq(LOAN_SYSTEM_USER.PARTNER_ID));

		contains(LOAN_SYSTEM_USER.NAME, searchRequest.getName());
		contains(LOAN_SYSTEM_USER.ACCOUNT, searchRequest.getAccount());
		contains(LOAN_SYSTEM_USER.EMAIL, searchRequest.getEmail());
		contains(LOAN_SYSTEM_USER.PHONE, searchRequest.getPhone());
		eq(LOAN_SYSTEM_USER.ENABLE, searchRequest.getEnable());
		eq(LOAN_SYSTEM_USER.LOCKED, searchRequest.getLocked());
		eq(LOAN_SYSTEM_USER.PARTNER_ID, searchRequest.getPartnerId());
		return search(pageable, new UserSearchResponseRecordMapper());
	}

	@Override
	public Integer updateLastLoginTimeAndResetRetryTimes(String account) {
		return dslContext.update(LOAN_SYSTEM_USER).set(LOAN_SYSTEM_USER.RETRY_TIMES, 0).set(LOAN_SYSTEM_USER.LAST_LOGIN_TIME, new Timestamp(System.currentTimeMillis()))
				.where(LOAN_SYSTEM_USER.ACCOUNT.eq(account)).execute();
	}

	@Override
	public List<SystemUser> findAllByRoleCode(String roleCode) {
		fields(LOAN_SYSTEM_USER.fields());
		innerJoin(LOAN_USER_ROLE, LOAN_USER_ROLE.USER_ID.eq(LOAN_SYSTEM_USER.ID));
		innerJoin(LOAN_ROLE, LOAN_USER_ROLE.ROLE_ID.eq(LOAN_ROLE.ID));
		eq(LOAN_ROLE.CODE, roleCode);
		return search(SystemUser.class);
	}

	private final class UserSearchResponseRecordMapper implements RecordMapper<Record, SystemUserSearchResponse> {

		@Override
		public SystemUserSearchResponse map(Record record) {
			SystemUserSearchResponse response = new SystemUserSearchResponse();
			response.setId(record.get(LOAN_SYSTEM_USER.ID));
			response.setName(record.get(LOAN_SYSTEM_USER.NAME));
			response.setAccount(record.get(LOAN_SYSTEM_USER.ACCOUNT));
			response.setEmail(record.get(LOAN_SYSTEM_USER.EMAIL));
			response.setEnable(record.get(LOAN_SYSTEM_USER.ENABLE));
			response.setLocked(record.get(LOAN_SYSTEM_USER.LOCKED));
			response.setPhone(record.get(LOAN_SYSTEM_USER.PHONE));
			response.setLastLoginTime(record.get(LOAN_SYSTEM_USER.LAST_LOGIN_TIME));
			response.setPartnerName(record.get(LOAN_PARTNER.NAME));
			response.setRelatedFunctionalPermission(record.get(LOAN_FUNCTIONAL_PERMISSION_RELATION.ID) != null);
			response.setRelatedDataPermission(record.get(LOAN_DATA_PERMISSION_RELATION.ID) != null);
			response.setRelatedRole(record.get(LOAN_USER_ROLE.ID) != null);
			return response;
		}
	}

}
